﻿using System;
using System.Messaging;
using System.Security.Principal;
using Microsoft.Build.Framework;
using NUnit.Framework;

namespace DotNet.DevOps.Tasks.Tests
{
    internal class TaskTestBase
    {
        /// <summary>
        /// Key methods for recreating the exact same Acceptance test. Is overridden in Acceptance tests.
        /// </summary>
        protected virtual bool ExecuteTask(ITask taskSetup)
        {
            return taskSetup.Execute();
        }

        protected void CheckUserIsAdministrator()
        {
            if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator) == false)
            {
                Assert.Ignore("Since user is not running as Administrator.");
            }
        }

        protected void AllowUserMSMQPermissions(string user)
        {
            SetUserOnQueue(user, @".\Private$\msbuildtestqueue",AccessControlEntryType.Allow);
            SetUserOnQueue(user, @".\Private$\msbuildtestqueue.errors", AccessControlEntryType.Allow);
            SetUserOnQueue(user, @".\Private$\msbuildtestqueue.subscriptionstorage", AccessControlEntryType.Allow);
        }

        protected void DenyUserMSMQPermissions(string user)
        {
            SetUserOnQueue(user, @".\Private$\msbuildtestqueue", AccessControlEntryType.Deny);
            SetUserOnQueue(user, @".\Private$\msbuildtestqueue.errors", AccessControlEntryType.Deny);
            SetUserOnQueue(user, @".\Private$\msbuildtestqueue.subscriptionstorage", AccessControlEntryType.Deny);
        }

        protected void DeleteMSMQS()
        {
            DeleteMSMQ(@".\Private$\msbuildtestqueue");
            DeleteMSMQ(@".\Private$\msbuildtestqueue.errors");
            DeleteMSMQ(@".\Private$\msbuildtestqueue.subscriptionstorage"); 
        }

        private void SetUserOnQueue(string user, string queue, AccessControlEntryType type)
        {
            if (MessageQueue.Exists(queue) == true)
            {
                var msmq = new MessageQueue(queue);
                msmq.ResetPermissions();
                msmq.SetPermissions(user, MessageQueueAccessRights.FullControl, type);
                msmq.Close();
            }
        }

        private void DeleteMSMQ(string queue)
        {
            if (MessageQueue.Exists(queue) == true)
            {
                MessageQueue.Delete(queue);
            }
        }


        protected void InvokeActionWithExceptionSupressing(Action action)
        {
            try
            {
                action.Invoke();
            }
            catch (Exception ex)
            {
            }
        }
    }
}
